package com.cskaoyan.javase.oop1._12block._1building._2usecase;

/**
 * 构造代码块的实践用途:
 *      1.构造代码块最大的特点就是其中的代码，最终会加入类的所有构造器中
 *      所以依据这一点：
 *      我们可以"提取公因式"一样的，把所有构造器都需要执行的代码，放入构造代码块中。
 *
 *      2.其次，构造代码块毕竟是给成员变量赋值用的，所以：
 *      如果需要很复杂的代码完成成员变量的赋值（如果只是给一个值，用显式赋值和构造器足矣）
 *      比如需要一个算法，需要一定计算等等。在这些场景下，使用构造代码块赋值也是一个不错的选择。
 *      在这种场景下,可以把构造代码块看成是一个在new对象过程中,自动被调用的成员方法
 *      所以用构造代码块给成员变量做复杂的赋值,要比成员方法更简单一点.
 *
 *
 * 思考: 在构造代码块中,可不可以给静态成员变量赋值?
 *      可以
 *      因为构造代码块在new对象过程中执行
 *      所以执行它时,类加载一定进行了,静态成员变量一定存在了,既然存在就可以赋值了.
 *      但是这个赋值要依赖于new对象的过程,不new对象就不能赋值
 *      所以我们期望一种能够在类加载过程中,完成静态成员变量赋值的代码块
 *      这就是静态代码块
 *
 * @since 09:45
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        System.out.println(Student.count);
        new Student("张三");
        for (int i = 0; i < 3; i++) {
            new Student();
        }
        for (int i = 0; i < 10; i++) {
            new Student("李四", 18, 1);
        }
        System.out.println(Student.count);
    }
}

class Student {
    // 要求: 在外部统计new Student对象的次数
    static int count = 0;
    String name;
    int age;
    int id;

    {
        count++;
    }

    public Student() {
        // count++;
    }

    public Student(String name) {
        // 如果该构造器第一行是this调用其他构造器
        // 那么构造代码块中的代码就不会加入该构造器,只需要加入this构造器,相当于这里也加了.
        // this();
        this.name = name;
        // count++;
    }

    public Student(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
        // count++;
    }
}